#include "precompiled.h"
#include "optimizepartial.h"
using namespace weo::engine::optimization;
using namespace weo::engine::character;
using namespace weo::engine::item;
using namespace std;
void OptimizePartial::OptimizeThreadRunner()
{
    m_Character->evaluateEquip(m_Equip.Items,m_Equip.Gems,m_Equip.Enchants);
    float maxfitness = m_Character->evaluateTF();
    m_Itemcount = 1;
    int notlockedslotslength = 0;
    int slotcounter = 0;
    for(int i = 0;i<weo::engine::Slotcount;i++)
    {
        if(!m_Locked[i])
        {
            m_NotLockedSlots[slotcounter++] = m_Itemcount;
            m_Itemcount *= m_Items[i].size();
            notlockedslotslength++;
        }
    }
    Equipment backup = m_Equip;
    unsigned int modvalue = (m_Itemcount < 100) ? m_Itemcount : m_Itemcount/100;
    unsigned int counter = 0;
    unsigned int slot = 0;
    m_Runtime.restart();
    unsigned int gemcount = m_Items[m_Gemindex].size();	
    while (counter < m_Itemcount)
    {
        if (m_Abort) break;
        slot = slot % weo::engine::Slotcount;
        if(m_Locked[slot])
        {
            slot++;
            continue;
        }
        m_StartLoop.restart();
        populateSlot(m_Equip.Items[slot],m_Equip.Gems[slot*3],m_Equip.Gems[slot*3+1],m_Equip.Gems[slot*3+2],m_Equip.Enchants[slot],slot,(counter / m_NotLockedSlots[counter % notlockedslotslength]) % m_Items[slot].size());
        m_Equip.Enchants[slot] = backup.Enchants[slot];
        const Item *item = m_Equip.Items[slot];
        int socketcount = item->Sockets()->Count();
        unsigned int gemmaxcount = (unsigned int) pow((double)gemcount,socketcount);
        unsigned int gemcounter = 0;
        while(gemcounter < gemmaxcount && socketcount > 0)
        {
            int gemslot = gemcounter % socketcount;
            const Item* gem = m_Items[m_Gemindex][(gemcounter / (unsigned int) pow((double) gemcount,gemslot)) % gemcount];
            if(item->Sockets()->Colors()->at(gemslot) == 8 && gem->Subtype() != 8)
            {
                gemcounter++;
                continue;
            }
            else if(item->Sockets()->Colors()->at(gemslot) != 8 && gem->Subtype() == 8)
            {
                gemcounter++;
                continue;
            }
            else
            {
                m_Equip.Gems[slot*3+gemslot] =  gem;
                if(Valid(m_Equip.Items,m_Equip.Gems,m_Equip.Enchants))
                {
                    m_Character->evaluateEquip(m_Equip.Items,m_Equip.Gems,m_Equip.Enchants);
                    float fitness = m_Character->evaluateTF();
                    if(fitness > maxfitness)
                    {
                        maxfitness = fitness;
                        backup = m_Equip;
                    }
                }
            }
            gemcounter++;
        }
        counter++;
        slot++;
        m_Equip = backup;
        if(counter % modvalue == 0)
        {
            m_UpdateSignal(maxfitness);
        }
    }
    m_Equip.Fitness = maxfitness;
    m_EndSignal();
}
void OptimizePartial::Optimize()
{
    boost::thread thrd(boost::bind(&OptimizePartial::OptimizeThreadRunner,this));
}
OptimizePartial::~OptimizePartial()
{
}